﻿using UnityEngine;
#if UNITY_STANDALONE_WIN
using System;
using System.IO;
using System.Text;
#endif

namespace Anderson.Utils
{
    public class AndersonLog : MonoBehaviour, ILog
    {
        #region Singlton
        void Awake()
        {
            if (_instance != null)
            {
                UnityEngine.Debug.LogErrorFormat("Another instance [{0}] of AndersonLog already exist",
                    _instance.gameObject.name);

                AndersonLog exist = _instance.gameObject.GetComponent<AndersonLog>();
                Destroy(exist);
            }

            _instance = this;
        }

        private static AndersonLog _instance = null;
        public static AndersonLog Instance()
        {
            return _instance;
        }
        #endregion

        #region Properties
        private DebugLevel Level = DebugLevel.DEBUG;
        #endregion

        #region ILog

        public DebugLevel GetLevel()
        {
            return Level;
        }

        public void SetLevel(DebugLevel level)
        {
            Level = level;
        }

        public void Trace(string message)
        {
            int level = (int)Instance().Level;
            if (level > (int)DebugLevel.TRACE)
            {
                return;
            }

            string log = string.Format("{0} - {1}", DebugLevel.TRACE.ToString(), message);
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
            LogToFile(log);
#else
            UnityEngine.Debug.Log(log);
#endif
        }

        public void Debug(string message)
        {
            int level = (int)Instance().Level;
            if (level > (int)DebugLevel.DEBUG)
            {
                return;
            }

            string log = string.Format("{0} - {1}", DebugLevel.DEBUG.ToString(), message);
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
            LogToFile(log);
#else
            UnityEngine.Debug.Log(log);
#endif
        }

        public void Info(string message)
        {
            int level = (int)Instance().Level;
            if (level > (int)DebugLevel.INFO)
            {
                return;
            }
            string log = string.Format("{0} - {1}", DebugLevel.INFO.ToString(), message);
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
            LogToFile(log);
#else
            UnityEngine.Debug.Log(log);
#endif
        }

        public void Warn(string message)
        {
            int level = (int)Instance().Level;
            if (level > (int)DebugLevel.WARN)
            {
                return;
            }

            string log = string.Format("{0} - {1}", DebugLevel.WARN.ToString(), message);
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
            LogToFile(log);
#else
            UnityEngine.Debug.LogWarning(log);
#endif
        }

        public void Error(string message)
        {
            int level = (int)Instance().Level;
            if (level > (int)DebugLevel.ERROR)
            {
                return;
            }

            string log = string.Format("{0} - {1}", DebugLevel.ERROR.ToString(), message);
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
            LogToFile(log);
#else
            UnityEngine.Debug.LogError(log);
#endif
        }

        public void Fatal(string message)
        {
            int level = (int)Instance().Level;
            if (level > (int)DebugLevel.FATAL)
            {
                return;
            }

            string log = string.Format("{0} - {1}", DebugLevel.FATAL.ToString(), message);
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
            LogToFile(log);
#else
            UnityEngine.Debug.LogError(log);
#endif
        }
        #endregion

        #region Log Message to File
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
        public static void LogToFile(string msg)
        {
            string logName = GetLoggerFile();

            StreamWriter sw = null;
            try
            {
                sw = new StreamWriter(logName, true, Encoding.UTF8);
                sw.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msg));
            }
            finally
            {
                sw.Close();
                sw.Dispose();
            }
        }

        private static string GetLoggerFile()
        {
            string loggerFileName = string.Format("{0}/{1}-{2}{3}",
                Application.dataPath, Application.productName, DateTime.Now.ToString("yyyy-MM-dd"), ".log");

            return loggerFileName;
        }
#endif
        #endregion
    }
}
